package com.cqcomponents.servlets;

import java.io.IOException;
import java.util.Iterator;

import javax.servlet.ServletException;

import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cqcomponents.utils.ComponentUtils;
import com.day.cq.wcm.api.WCMMode;

/**
 * lists all cqcomponents below a resource so that they can be referenced
 * 
 * @author juju
 * 
 */

@SlingServlet(paths = { "/bin/cqcomponents/cqcomponentslist" })
public class CQComponentsListServlet extends SlingSafeMethodsServlet {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 
	 */
	private static final long serialVersionUID = -3802536443904502295L;

	@Override
	protected void doGet(SlingHttpServletRequest request,
			SlingHttpServletResponse response) throws ServletException,
			IOException {
		String path = request.getParameter("path");
		if (StringUtils.isBlank(path)) {
			path = "/content";
		}
		Resource resource = request.getResourceResolver().getResource(path);

		Iterator<Resource> iterator = resource.getResourceResolver()
				.listChildren(resource);

		int count = 0;
		JSONObject result = new JSONObject();
		JSONArray components = new JSONArray();

		try {
			result.put("cqcomponents", components);
			while (iterator.hasNext()) {
				Resource child = iterator.next();
				if (isReferenceableCQCComponent(child)) {
					// This is a cqcomponent --> grab content
					String html = grabContent(child.getPath(), request,
							response);
					String resourceType = child.getResourceType();
					Resource componentResource = child.getResourceResolver()
							.getResource(resourceType);
					String defaultName = ResourceUtil.getName(componentResource
							.getPath());
					String name = ResourceUtil.getValueMap(componentResource)
							.get("jcr:title", defaultName);

					JSONObject object = new JSONObject();
					object.put("html", html);
					object.put("path", child.getPath());
					object.put("name", name);
					count++;

					components.put(object);
				}

			}
			result.put("count", count);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

		response.setContentType("application/json");

		response.getWriter().write(result.toString());
	}

	/**
	 * All cqc components are referenceable except: cqc page components and
	 * subcomponents, cqc contentreference components and subcomponents
	 * 
	 * @param child
	 * @return
	 */
	private boolean isReferenceableCQCComponent(Resource resource) {

		return !ComponentUtils.isPageComponent(resource)
				&& !ComponentUtils.isContentReferenceComponent(resource)
				&& ComponentUtils.isCQCComponent(resource);
	}

	private String grabContent(String path, SlingHttpServletRequest request,
			SlingHttpServletResponse response) throws ServletException,
			IOException {
		CapturingHttpServletResponseWrapper wrapper = new CapturingHttpServletResponseWrapper(
				response);
		WCMMode currentWCMMode = WCMMode.fromRequest(request);
		// Switch to WCMMode disabled
		WCMMode.DISABLED.toRequest(request);

		request.getRequestDispatcher(path + ".html").include(request, wrapper);

		// Restore wcmmode
		currentWCMMode.toRequest(request);
		return wrapper.getContent();
	}
}
